package com.mainbo.modular.system.controller;

import cn.stylefeng.roses.core.base.controller.BaseController;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.mainbo.core.log.LogObjectHolder;
import com.mainbo.core.shiro.SessionKey;
import com.mainbo.core.shiro.ShiroKit;
import com.mainbo.core.util.Result;
import com.mainbo.core.util.StringUtil;
import com.mainbo.core.util.WebThreadLocalUtils;
import com.mainbo.modular.excel.BatchClassService;
import com.mainbo.modular.excel.ClassUserBatchStudentService;
import com.mainbo.modular.excel.ClassUserBatchTeacherService;
import com.mainbo.modular.jms.JmsService;
import com.mainbo.modular.jms.MessageTypes;
import com.mainbo.modular.jms.model.ClassInfoMessage;
import com.mainbo.modular.jms.model.ClassUserMessage;
import com.mainbo.modular.system.dao.PtClassMapper;
import com.mainbo.modular.system.dao.PtClassUserMapper;
import com.mainbo.modular.system.dao.PtSchoolClassroomMapper;
import com.mainbo.modular.system.dao.PtTeacherMapper;
import com.mainbo.modular.system.model.*;
import com.mainbo.modular.system.model.PtClass.ClassInfoStatus;
import com.mainbo.modular.system.model.meta.ConfigConstants;
import com.mainbo.modular.system.model.meta.MetaUtils;
import com.mainbo.modular.system.model.meta.vo.Meta;
import com.mainbo.modular.system.model.vo.SubjectTeacherVo;
import com.mainbo.modular.system.model.vo.UserVo;
import com.mainbo.modular.system.service.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 控制器
 *
 * @author fengshuonan
 * @Date 2020-02-24 11:28:27
 */
@Controller
@RequestMapping("/ptClass")
public class PtClassController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(PtClassController.class);
    private String PREFIX = "/system/ptClass/";


    @Resource
    private IPtClassService ptClassService;
    @Resource
    private IPtOrgService orgService;
    @Resource
    private IPtUserRoleService ptUserRoleService;
    @Resource
    private IPtSchoolClassroomService schoolClassroomService;
    @Resource
    private IPtClassUserService ptClassUserService;
    @Resource
    private PtTeacherMapper teacherMapper;
    @Resource
    private JmsService jmsService;
    @Resource
    private StudentService studentService;
    @Resource
    private IPtAccountService accountService;
    @Resource
    private BatchClassService batchClassService;
    @Resource
    private ClassUserBatchStudentService classUserBatchStudentService;
    @Resource
    private ClassUserBatchTeacherService classUserBatchTeacherService;
    @Resource
    private PtClassMapper classMapper;
    @Resource
    private PtClassUserMapper classUserMapper;
    @Resource
    private PtSchoolClassroomMapper schoolClassroomMapper;

    /**
     * 跳转到首页
     */
    @RequestMapping("")
    public String index(Model model) {
        PtOrg org = ShiroKit.getSessionAttr(SessionKey.CURRENT_ORG);
        if ((org == null)) {
            model.addAttribute("orgId", "0");
            return PREFIX + "ptClass_org.html";
        }
        // 学校的学段集合
        List<Meta> phaseList = MetaUtils.getOrgTypeProvider()
                .listAllPhase(org.getSchoolings());
        // 学校的学段-年级map
        Map<Integer, List<Meta>> phasegradeMap = MetaUtils.getOrgTypeProvider()
                .listPhaseXzGradeMap(org.getSchoolings());
        Integer currentSchoolYear = MetaUtils.getSchoolYearProvider().getCurrentSchoolYear();
        model.addAttribute("currentSchoolYear", currentSchoolYear);
        model.addAttribute("phaseList", phaseList);
        model.addAttribute("phase_gradeMap", JSONObject.toJSON(phasegradeMap));
        model.addAttribute("schoolYearList", createHistoryList(org.getId()));
        model.addAttribute("orgId", org.getId());
        return PREFIX + "ptClass_list.html";

    }

    /**
     * 跳转到添加
     */
    @RequestMapping("/ptClass_add")
    public String ptClassAdd(String orgId, Model model) {
        PtOrg org = orgService.selectById(orgId);
        model.addAttribute("org", org);
        model.addAttribute("periodList", createPeriodList(org.getId()));
        // 学校的学段集合
        List<Meta> phaseList = MetaUtils.getOrgTypeProvider()
                .listAllPhase(org.getSchoolings());
        // 学校的学段-年级map
        Map<Integer, List<Meta>> phasegradeMap = MetaUtils.getOrgTypeProvider()
                .listPhaseXzGradeMap(org.getSchoolings());


        model.addAttribute("phaseList", phaseList);

        model.addAttribute("phase_gradeMap", JSONObject.toJSON(phasegradeMap));
        model.addAttribute("classTypeList", MetaUtils.listMeta(ConfigConstants.CLASS_TYPE));
        return PREFIX + "ptClass_add.html";
    }

    /**
     * 跳转到修改
     */
    @RequestMapping("/ptClass_update/{ptClassId}")
    public String ptClassUpdate(@PathVariable String ptClassId, Model model) {
        PtClass ptClass = ptClassService.selectById(ptClassId);
        PtOrg org = orgService.selectById(ptClass.getOrgId());
        model.addAttribute("periodList", createPeriodList(org.getId()));
        // 学校的学段集合
        List<Meta> phaseList = MetaUtils.getOrgTypeProvider()
                .listAllPhase(org.getSchoolings());
        // 学校的学段-年级map
        Map<Integer, List<Meta>> phasegradeMap = MetaUtils.getOrgTypeProvider()
                .listPhaseXzGradeMap(org.getSchoolings());
        model.addAttribute("phaseList", phaseList);
        model.addAttribute("phase_gradeMap", JSONObject.toJSON(phasegradeMap));
        model.addAttribute("classTypeList", MetaUtils.listMeta(ConfigConstants.CLASS_TYPE));
        model.addAttribute("item", ptClass);
        LogObjectHolder.me().set(ptClass);
        return PREFIX + "ptClass_edit.html";
    }

    /**
     * 跳转到查看
     */
    @RequestMapping("/ptClass_showInfo/{ptClassId}")
    public String ptClassShowInfo(@PathVariable String ptClassId, Model model) {
        PtClass ptClass = ptClassService.selectById(ptClassId);
        PtOrg org = orgService.selectById(ptClass.getOrgId());
        if (ptClass.getPhaseId() != null) {
            ptClass.setPhase(MetaUtils.getMeta(ptClass.getPhaseId()).getName());
        }
        if (ptClass.getGradeId() != null) {
            ptClass.setGrade(MetaUtils.getMeta(ptClass.getGradeId()).getName());
        }
        if (ptClass.getClassType() != null) {
            ptClass.setClassTypeName(MetaUtils.getMeta(ptClass.getClassType()).getName());
        }
        model.addAttribute("item", ptClass);
        LogObjectHolder.me().set(ptClass);
        return PREFIX + "ptClass_view.html";
    }

    /**
     * 获取列表
     */
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(PtClass ptClass) {
        // 分页获取班级
        if (ptClass.getSchoolYear() == null) {
            ptClass.setSchoolYear(
                    MetaUtils.getSchoolYearProvider().getCurrentSchoolYear(ptClass.getId()));
        }
        List<PtClass> classList = ptClassService.getClassList(ptClass);
        if (classList.size() > 0) {
            for (PtClass temp : classList) {
                // 升级状态
                Integer status = temp.getStatus() == null ? PtClass.update_not_begin
                        : temp.getStatus();
                temp.setStatusName(ClassInfoStatus.getValueById(status).getCname());
                // 毕业状态
                Integer graduationStatus = temp.getGraduationStatus() == null
                        ? PtClass.not_graduation : temp.getGraduationStatus();
                String graduationStatusName = ClassInfoStatus
                        .getValueById(graduationStatus).getCname();
                if (PtClass.phase_graduation.equals(graduationStatus)) {
                    Meta meta = MetaUtils.getMeta(temp.getPhaseId());
                    String phaseName = "";
                    if (meta != null) {
                        phaseName = meta.getName();
                    }
                    graduationStatusName = phaseName + graduationStatusName;
                } else if (PtClass.school_graduation.equals(graduationStatus)) {
                    temp.setStatusName(
                            ClassInfoStatus.getValueById(PtClass.update_not_need).getCname());
                }
                temp.setGraduationStatusName(graduationStatusName);
            }
        }
        return classList;

    }

    /**
     * 生成级届集合
     *
     * @param orgId
     * @return List
     */
    private List<Integer> createHistoryList(String orgId) {
        int count = 10;
        List<Integer> periodList = new ArrayList<Integer>();
        Integer courrentPeriod = MetaUtils.getSchoolYearProvider()
                .getCurrentSchoolYear(orgId) + 1;
        for (int i = 0; i < count; i++) {
            periodList.add(courrentPeriod);
            courrentPeriod--;
        }
        return periodList;
    }

    /**
     * 生成级届集合
     *
     * @param orgId
     * @return List
     */
    private List<Integer> createPeriodList(String orgId) {
        int count = 10;
        List<Integer> periodList = new ArrayList<Integer>();
        Integer courrentPeriod = Integer.valueOf(new SimpleDateFormat("yyyy").format(new Date()));

        for (int i = 0; i < count; i++) {
            periodList.add(courrentPeriod);
            courrentPeriod++;
        }

        return periodList;
    }

    /**
     * 新增
     */
    @RequestMapping(value = "/add")
    @ResponseBody
    public Result add(PtClass ptClass) {
        Result result = new Result();
        result.setCode(Result.SUCCESS);
        try {
            result = ptClassService.saveOrUpdateClass(ptClass, result);

        } catch (Exception e) {
            result.setCode(Result.FAIL);
            result.setMsg("保存失败");
            logger.error("组织机构管理——班级管理——班级保存失败", e);
        }
        return result;
    }

    /**
     * 删除班级
     *
     * @param id 班级id
     * @return result
     */
    @RequestMapping("/deleteClass/{id}")
    @ResponseBody
    public Result deleteClass(@PathVariable String id) {
        Result result = new Result();
        result.setCode(Result.SUCCESS);
        try {
            PtClass classInfo = ptClassService.selectById(id);
            if (StringUtils.isNotBlank(classInfo.getClassroomId())) {
                PtSchoolClassroom room = new PtSchoolClassroom();
                room.setId(classInfo.getClassroomId());
                room.setIsUsed(0);
                schoolClassroomService.updateById(room);
            }
            ptClassService.deleteClass(id);
            result.setMsg("删除成功");
        } catch (Exception e) {
            result.setCode(Result.FAIL);
            result.setMsg("删除失败");
            logger.error("组织机构管理——班级管理——删除班级失败", e);
        }
        return result;
    }

    /**
     * 修改
     */
    @RequestMapping(value = "/update")
    @ResponseBody
    public Object update(PtClass ptClass) {
        ptClassService.updateById(ptClass);
        return SUCCESS_TIP;
    }

    /**
     * 配置任课教师
     *
     * @param id 班级id
     * @param m  Model
     * @return String
     */
    @RequestMapping("/editClassTeacher/{id}")
    public String editClassTeacher(@PathVariable String id, Model m) {
        PtClass ptClass = ptClassService.selectById(id);
        PtOrg org = orgService.selectById(ptClass.getOrgId());
        // 根据学校和学段获取相应的科目集合
        List<Meta> subjectList = MetaUtils.getPhaseSubjectProvider()
                .listAllSubject(org.getId(), ptClass.getPhaseId(),
                        StringUtil.toIntegerArray(org.getAreaIds().substring(1, org.getAreaIds().length() - 1),
                                ","));
        // 获取科目——教师map
        Map<Integer, Teacher> subjectteacherMap = ptClassUserService
                .getSubjectTeacherMap(id);
        m.addAttribute("subjectTeacherMap", JSON.toJSON(subjectteacherMap));
        m.addAttribute("subjectList", subjectList);
        m.addAttribute("ptClass", ptClass);
        return PREFIX + "ptClass_editClassTeacher.html";
    }

    private List<SubjectTeacherVo> getSubjectTeachers(List<Meta> subjectList, String orgId, Integer phaseId) {
        List<SubjectTeacherVo> list = new ArrayList<>();
        for (Meta meta : subjectList) {
            SubjectTeacherVo subjectTeacherVo = new SubjectTeacherVo();
            subjectTeacherVo.setSubjectId(meta.getId());
            subjectTeacherVo.setSubjectName(meta.getName());
            PtUserRole userRole = new PtUserRole();
            userRole.setSubjectId(meta.getId());
            userRole.setOrgId(orgId);
            userRole.setPhaseId(phaseId);
            List<UserVo> teachers = suggestTeacherList(userRole);
            subjectTeacherVo.setTeacherList(teachers);
            list.add(subjectTeacherVo);
        }
        return list;

    }

    /**
     * 根据参数获取老师集合
     *
     * @param userRole 用户身份
     * @return List
     */
    @RequestMapping("/suggestTeacherList")
    @ResponseBody
    public List<UserVo> suggestTeacherList(PtUserRole userRole) {
        List<PtUserRole> teacherList = ptUserRoleService
                .listTeacherByOrg_Phase_Subject(userRole);
        List<UserVo> teacherVos = new ArrayList<>();
        for (PtUserRole t : teacherList) {
            UserVo teacherVo = new UserVo();
            teacherVo.setUserId(t.getAccountId());
            teacherVo.setUserName(t.getName());
            teacherVos.add(teacherVo);
        }
        return teacherVos;
    }

    /**
     * 根据参数获取老师集合
     *
     * @param userRole 用户身份
     * @return List
     */
    @RequestMapping("/suggestTeacherList1")
    @ResponseBody
    public List<PtUserRole> suggestTeacherList1(PtUserRole userRole) {
        List<PtUserRole> teacherList = ptUserRoleService.findHeadmaster(userRole);

        return teacherList;
    }


    /**
     * 保存班级和任课老师对应关系
     *
     * @param classUserVo 班级用户
     * @param m           Model
     * @return JuiResult
     */
    @RequestMapping("/saveClassTeacher")
    @ResponseBody
    public Result saveClassTeacher(ClassUserMessage classUserVo, Model m) {
        Result result = new Result();
        try {
            List<PtClassUser> classUserList = classUserVo.getClassUserList();
            for (PtClassUser classUser : classUserList) {
                if (StringUtils.isNotBlank(classUser.getUserId())) {
                    Teacher teacher = teacherMapper.selectById(classUser.getUserId());
                    if (teacher == null) {
                        result.setCode(Result.FAIL);
                        result.setMsg(MetaUtils.getMeta(classUser.getSubjectId()).getName() + "科目下的该教师账号不存在");
                        return result;
                    } else {
                        classUser.setUserName(teacher.getName());
                    }
                }
            }
            classUserVo.setType(PtClassUser.TYPE_TEACHER);
            classUserVo.setStartTime(new Date());
            ptClassUserService.saveOrUpdateClassUser(classUserVo,
                    PtClassUser.TYPE_TEACHER);
            result.setCode(Result.SUCCESS);
            result.setMsg("保存成功");
            classUserVo.setEndTime(new Date());
            try {
                classUserVo.setSchoolYear(classUserVo.getSchoolYear());
                classUserVo.setMessageType(MessageTypes.CLASS_TEACHER_INSERT.name());
                jmsService.sendMessage(classUserVo);
            } catch (Exception e) {
                logger.error("组织机构管理——班级管理——批量增加班级任课教师——消息发送失败", e);
            }
        } catch (Exception e) {
            result.setCode(Result.FAIL);
            result.setMsg("保存失败");
            logger.error("组织机构管理——班级管理——班级和任课老师对应关系保存失败", e);
        }
        return result;
    }

    /**
     * 学生管理页
     *
     * @param id 班级id
     * @param m  Model
     * @return String
     */
    @RequestMapping("/editClassStudent/{id}")
    public String editClassStudent(@PathVariable String id, Model m) {
        PtClass ptClass = ptClassService.selectById(id);
        m.addAttribute("ptClass", ptClass);
        return PREFIX + "ptClass_editClassStudent.html";
    }

    /**
     * 学生添加页
     *
     * @param m
     * @return
     */
    @RequestMapping("/addClassStudent")
    public String addClassStudent(String classId, Student student, Model m) {
        List<Student> sList = studentService.findStudentsWithoutClass(student);
        m.addAttribute("item", student);
        m.addAttribute("classId", classId);
        m.addAttribute("studentList", sList);
        return PREFIX + "ptClass_addStudent.html";
    }

    @RequestMapping("/findStudentList/{classId}")
    @ResponseBody
    public List<PtClassUser> findStudentList(@PathVariable String classId) {
        EntityWrapper<PtClassUser> cu = new EntityWrapper<>();
        cu.eq("class_id", classId);
        cu.eq("type", PtClassUser.TYPE_STUDENT);
        cu.eq("enable", 1);
        return ptClassUserService.selectList(cu);
    }

    /**
     * 获取未分配班级的学生信息集合
     *
     * @param student 学生
     * @return List
     */
    @RequestMapping("/suggestStudentList")
    @ResponseBody
    public List<UserVo> suggestStudentList(Student student) {
        List<Student> sList = studentService.findStudentsWithoutClass(student);
        List<UserVo> userVos = new ArrayList<>();
        for (Student s : sList) {
            UserVo userVo = new UserVo();
            userVo.setUserId(s.getId());
            userVo.setUserName(s.getName());
            userVos.add(userVo);
        }
        return userVos;
    }


    /**
     * 保存班级和学生对应关系
     *
     * @param classUserVo 班级用户
     * @param m           Model
     * @return JuiResult
     */
    @RequestMapping("/saveClassStudent")
    @ResponseBody
    public Result saveClassStudent(ClassUserMessage classUserVo, Model m) {
        Result result = new Result();
        result.setCode(Result.SUCCESS);
        try {
            PtAccount account = accountService.findAccountWithInfo(classUserVo.getUserId());
            List<PtClassUser> classUserList = new ArrayList<>();
            PtClassUser classUser = new PtClassUser();
            classUser.setSchoolYear(classUserVo.getSchoolYear());
            classUser.setOrgId(classUserVo.getOrgId());
            classUser.setUserId(classUserVo.getUserId());
            classUser.setUserName(account.getUserInfo().getName());
            classUserList.add(classUser);
            classUserVo.setClassUserList(classUserList);
            classUserVo.setType(PtClassUser.TYPE_STUDENT);
            classUserVo.setStartTime(new Date());
            ptClassUserService.saveOrUpdateClassUser(classUserVo,
                    PtClassUser.TYPE_STUDENT);
            result.setMsg("保存成功");
            classUserVo.setEndTime(new Date());
            try {
                classUserVo.setSchoolYear(classUserVo.getSchoolYear());
                classUserVo.setMessageType(MessageTypes.CLASS_STUDENT_INSERT.name());
                jmsService.sendMessage(classUserVo);
            } catch (Exception e) {
                logger.error("组织机构管理——班级管理——批量增加班级学生关联关系——消息发送失败", e);
            }
        } catch (Exception e) {
            result.setCode(Result.FAIL);
            result.setMsg("保存失败");
            logger.error("组织机构管理——班级管理——班级和学生对应关系保存失败", e);
        }
        return result;
    }

    /**
     * 删除班级和学生对应关系
     *
     * @param id 关系id
     * @return JuiResult
     */
    @RequestMapping("/deleteClassUser/{id}")
    @ResponseBody
    public Result deleteClassUser(@PathVariable String id) {
        Result result = new Result();
        result.setCode(Result.SUCCESS);
        try {
            PtClassUser cu = ptClassUserService.selectById(id);
            ptClassUserService.deleteById(id);
            result.setMsg("删除成功");
//            LoggerUtils.deleteLogger(LoggerModule.ORGMANAGE,
//                    "组织结构管理——班级管理——删除班级和学生对应关系，ID:{}", id);
            // 发送消息
            ClassUserMessage classUserVo = new ClassUserMessage();
            try {
                BeanUtils.copyProperties(cu, classUserVo);
                classUserVo.setMessageType(MessageTypes.CLASS_STUDENT_DELETE.name());
                jmsService.sendMessage(classUserVo);
            } catch (Exception e) {
                logger.error("组织机构管理——班级管理——发送‘删除班级和学生对应关系’消息失败", e);
            }
        } catch (Exception e) {
            result.setCode(Result.FAIL);
            result.setMsg("删除失败");
            logger.error("组织机构管理——班级管理——删除班级和学生对应关系失败", e);
        }
        return result;
    }

    /**
     * 删除班级和学生对应关系
     *
     * @param 关系id
     * @return JuiResult
     */
    @RequestMapping("/deleteClassUserByUserId/{userId}")
    @ResponseBody
    public Result deleteClassUserByUserId(@PathVariable String userId, Integer schoolYear) {
        Result result = new Result();
        result.setCode(Result.SUCCESS);
        try {
            EntityWrapper<PtClassUser> entityWrapper = new EntityWrapper<>();
            entityWrapper.eq("user_id", userId);
            entityWrapper.eq("school_year", schoolYear);
            List<PtClassUser> cu = ptClassUserService.selectList(entityWrapper);
            for (PtClassUser ptClassUser : cu) {
                ptClassUserService.deleteById(ptClassUser.getId());
                ClassUserMessage classUserVo = new ClassUserMessage();
                try {
                    BeanUtils.copyProperties(cu, classUserVo);
                    classUserVo.setMessageType(MessageTypes.CLASS_STUDENT_DELETE.name());
                    jmsService.sendMessage(classUserVo);
                } catch (Exception e) {
                    logger.error("组织机构管理——班级管理——发送‘删除班级和学生对应关系’消息失败", e);
                }
            }

            result.setMsg("删除成功");

        } catch (Exception e) {
            result.setCode(Result.FAIL);
            result.setMsg("删除失败");
            logger.error("组织机构管理——班级管理——删除班级和学生对应关系失败", e);
        }
        return result;
    }

    /**
     * 批量导入班级
     *
     * @param orgId 机构id
     * @param m     Model
     * @return String
     */
    @RequestMapping("/toBatchClass")
    public String toBatchClass(String orgId, Integer schoolYear, Model m, HttpServletRequest request) {
        m.addAttribute("orgId", orgId);
        m.addAttribute("schoolYear", schoolYear);
        m.addAttribute("prefix", WebThreadLocalUtils.getPrefixUrl(request));
        return PREFIX + "batchClass.html";
    }


    /**
     * 下载批量导入班级模板
     *
     * @param orgId    机构id
     * @param response HttpServletResponse
     */
    @RequestMapping("/downLoadRegisterClassTemplate")
    public void downLoadBatchManageClassTemplate(String orgId, HttpServletResponse response, Integer schoolYear) {
        try {
            batchClassService.downloadBatchClassTemplate(orgId, response, schoolYear);
        } catch (Exception e) {
            logger.error("下载批量关联班级模板出错！", e);
        }
    }

    /**
     * 批量导入班级
     *
     * @param orgId 机构id
     * @param file  文件
     * @param m     Model
     * @return String
     */
    @RequestMapping("batchImportClass")
    @ResponseBody
    public Result batchImportClass(String orgId, MultipartFile file, Integer schoolYear, Model m) {
        Result result = new Result();
        try {

            StringBuilder resultBuffer = null;
            resultBuffer = batchClassService.batchImportClass(orgId, file,
                    schoolYear);
            if (StringUtils.isBlank(resultBuffer)) {
                result.setCode(Result.SUCCESS);
                result.setMsg("恭喜您，批量导入全部完成");
            } else {
                result.setCode(Result.FAIL);
                result.setMsg(resultBuffer.toString());
            }
            m.addAttribute("flag", "class");
        } catch (Exception e) {
            result.setCode(Result.FAIL);
            logger.error("批量导入班级出错", e);
            result.setMsg("系统错误");
        }
        return result;
    }

    /**
     * 批量维护任课教师
     *
     * @param orgId      机构id
     * @param schoolYear 学年
     * @param m          Model
     * @return String
     */
    @RequestMapping("/toBatchTeacher")
    public String toBatchTeacher(String orgId, Integer schoolYear, Model m, HttpServletRequest request) {
        m.addAttribute("orgId", orgId);
        m.addAttribute("schoolYear", schoolYear);
        m.addAttribute("prefix", WebThreadLocalUtils.getPrefixUrl(request));
        return PREFIX + "batch_ImportTeacher.html";
    }

    /**
     * 批量添加学生
     *
     * @param orgId 机构id
     * @param m     Model
     * @return String
     */
    @RequestMapping("/toBatchStudent")
    public String toBatchStudent(String orgId, Integer schoolYear, Model m, HttpServletRequest request) {
        m.addAttribute("orgId", orgId);
        m.addAttribute("schoolYear", schoolYear);
        m.addAttribute("prefix", WebThreadLocalUtils.getPrefixUrl(request));
        return PREFIX + "batch_ImportStudent.html";
    }

    /**
     * 下载批量关联任课教师的模板
     *
     * @param orgId    机构id
     * @param response HttpServletResponse
     */
    @RequestMapping("/downLoadRegisterTeacherTemplate")
    public void downLoadBatchManageTeacherTemplate(String orgId,
                                                   HttpServletResponse response, Integer schoolYear) {
        try {
            classUserBatchTeacherService.downloadBatchManageTeacherTemplate(orgId,
                    response, schoolYear);
        } catch (Exception e) {
            logger.error("下载批量关联任课教师模板出错！", e);
        }
    }

    /**
     * 下载批量关联学生的模板
     *
     * @param orgId    机构id
     * @param response HttpServletResponse
     */
    @RequestMapping("/downLoadRegisterStudentTemplate")
    public void downLoadBatchManageStudentTemplate(String orgId,
                                                   HttpServletResponse response, Integer schoolYear) {
        try {
            classUserBatchStudentService.downloadBatchManageStudentTemplate(orgId,
                    response, schoolYear);
        } catch (Exception e) {
            logger.error("下载批量关联学生模板出错！", e);
        }
    }


    /**
     * 批量导入班级与任课教师的关联关系
     *
     * @param orgId 机构id
     * @param file  文件
     * @param m     Model
     * @return String
     */
    @RequestMapping("batchImportTeacher")
    @ResponseBody
    public Result batchImportTeacher(String orgId, MultipartFile file, Integer schoolYear) {
        Result result = new Result();
        try {
            StringBuilder resultBuffer = null;
            resultBuffer = classUserBatchTeacherService.batchImportTeacher(orgId,
                    file, schoolYear);
            if (StringUtils.isBlank(resultBuffer)) {
                result.setCode(Result.SUCCESS);
                result.setMsg("恭喜您，批量导入全部完成");
            } else {
                result.setCode(Result.SUCCESS);
                result.setMsg(resultBuffer.toString());
            }
        } catch (Exception e) {
            result.setCode(Result.FAIL);
            logger.error("批量导入教师出错", e);
            result.setMsg("系统错误");
        }
        return result;
    }

    /**
     * 批量导入班级学生关联关系
     *
     * @param orgId 机构id
     * @param file  文件
     * @param m     Model
     * @return String
     */
    @RequestMapping("batchImportStudent")
    @ResponseBody
    public Result batchImportStudent(String orgId, MultipartFile file, Integer schoolYear) {
        Result result = new Result();
        try {
            StringBuilder resultBuffer = null;
            resultBuffer = classUserBatchStudentService.batchImportStudent(orgId,
                    file, schoolYear);
            if (StringUtils.isBlank(resultBuffer)) {
                result.setCode(Result.SUCCESS);
                result.setMsg("恭喜您，批量导入全部完成");
            } else {
                result.setCode(Result.SUCCESS);
                result.setMsg(resultBuffer.toString());
            }
        } catch (Exception e) {
            result.setCode(Result.FAIL);
            logger.error("批量导入学生出错", e);
            result.setMsg("系统错误");
        }
        return result;
    }


    /**
     * 跳转升级班级
     *
     * @param orgId 机构id
     * @param m     Model
     * @return String
     */
    @RequestMapping("/classupdate/selectclassindex")
    public String xj_selectclass(String orgId, Integer schoolYear, Model m) {
        PtOrg org = orgService.selectById(orgId);
        // 学校的学段集合
        List<Meta> phaseList = MetaUtils.getOrgTypeProvider()
                .listAllPhase(org.getSchoolings());
        // 学校的学段-年级map
        Map<Integer, List<Meta>> phasegradeMap = MetaUtils.getOrgTypeProvider()
                .listPhaseXzGradeMap(org.getSchoolings());
        m.addAttribute("phaseList", phaseList);
        m.addAttribute("phase_gradeMap", JSONObject.toJSON(phasegradeMap));
        m.addAttribute("org", org);
        m.addAttribute("schoolYear", schoolYear);
        return PREFIX + "classupdate/selectclassindex.html";
    }

    /**
     * 根据学段年级查找需要升级的班级
     *
     * @param orgId      机构id
     * @param phaseId    学段id
     * @param gradeId    年级id
     * @param schoolYear 学年id
     * @return List
     */
    @RequestMapping("/classupdate/getAllClass")
    @ResponseBody
    public List<PtClass> xj_getAllclasses(String orgId, Integer phaseId,
                                          Integer gradeId, Integer schoolYear) {
        List<PtClass> classInfos = ptClassService.getAllclasses(orgId,
                phaseId, gradeId, schoolYear);
        return classInfos;
    }

    /**
     * 根据学段年级查找已升级的班级
     *
     * @param orgId      机构id
     * @param phaseId    学段id
     * @param gradeId    年级id
     * @param shcoolYear 学年id
     */
    @RequestMapping("/classupdate/selectedclasses")
    @ResponseBody
    public List<PtClass> xj_getSelectedclasses(String orgId, Integer phaseId,
                                               Integer gradeId, Integer schoolYear) {
        List<PtClass> selectedClassInfos = ptClassService
                .getSelectedclasses(orgId, phaseId, gradeId, null, schoolYear);
        return selectedClassInfos;
    }


    /**
     * 修改状态
     *
     * @param classIds 班级id
     * @param status   状态
     */
    @RequestMapping("/classupdate/changeClassStatus")
    public void xj_changeClassStatus(String classIds, Integer status, HttpServletResponse response) {
        ptClassService.changeClassStatus(classIds, status);
    }


    /**
     * 升级：新增或修改班级
     *
     * @param model 班级
     * @param m     Model
     * @return String
     */
    @RequestMapping("/classupdate/editClass")
    public String xj_toEditClass(PtClass model, Model m) {

        PtClass oldClass = ptClassService.selectById(model.getFromClassId());
        if (oldClass != null) {
            // 获取升级后的班级
            PtClass info = new PtClass();
            info.setFromClassId(model.getFromClassId());
            PtClass xjInfo = this.classMapper.selectOne(info);
            if (xjInfo == null) {
                xjInfo = new PtClass();
                BeanUtils.copyProperties(oldClass, xjInfo);
                xjInfo.setId(null);
            }
            m.addAttribute("ptClass", xjInfo);
            m.addAttribute("oldClass", oldClass);
        }
        PtOrg org = orgService.selectById(model.getOrgId());
        // 学校的学段集合
        List<Meta> phaseList = MetaUtils.getOrgTypeProvider()
                .listAllPhase(org.getSchoolings());
        // 学校的学段-年级map
        Map<Integer, List<Meta>> phasegradeMap = MetaUtils.getOrgTypeProvider()
                .listPhaseXzGradeMap(org.getSchoolings());
        m.addAttribute("phaseList", phaseList);
        m.addAttribute("phase_gradeMap", JSONObject.toJSON(phasegradeMap));
        m.addAttribute("org", org);
        m.addAttribute("periodList", createPeriodList(model.getOrgId()));
        m.addAttribute("schoolYear", model.getSchoolYear());

        m.addAttribute("classTypeList", MetaUtils.listMeta(ConfigConstants.CLASS_TYPE));
        m.addAttribute("subjectTypes", MetaUtils.listMeta(ConfigConstants.SYS_DEP_SYSTEM_CODE));
        PtUserRole userRole = new PtUserRole();
        userRole.setOrgId(org.getId());
        List<PtUserRole> headmasters = ptUserRoleService.findHeadmaster(userRole);
        m.addAttribute("headmasters", headmasters);
        m.addAttribute("classIds", model.getClassIds());
        fillNextClass(model.getFromClassId(), model.getClassIds(), m);
        return PREFIX + "classupdate/editClass.html";
    }

    private void fillNextClass(String classId, String classIds, Model m) {
        // 获取需要升级的下一个班级和上一个班级
        List<PtClass> needUpdateClasses = this.ptClassService
                .getSelectedclasses(null, null, null, classIds, null);
        List<String> updateClassIds = new ArrayList<String>();
        if (!CollectionUtils.isEmpty(needUpdateClasses)) {
            for (PtClass classInfo : needUpdateClasses) {
                updateClassIds.add(classInfo.getId());
            }
        }
        int index = updateClassIds.indexOf(classId);
        PtClass preClassInfo = new PtClass();
        PtClass nextClassInfo = new PtClass();
        if (index != -1) {
            if (index > 0) {
                preClassInfo = needUpdateClasses.get(index - 1);
            }
            if (index < updateClassIds.size() - 1) {
                nextClassInfo = needUpdateClasses.get(index + 1);
            }
        }
        m.addAttribute("preClassInfo", preClassInfo);
        m.addAttribute("nextClassInfo", nextClassInfo);
    }

    /**
     * 升级：配置任课教师
     *
     * @param info 班级
     * @param m    Model
     * @return String
     */
    @RequestMapping("/classupdate/editClassTeacher")
    public String xj_editClassTeacher(PtClass info, Model m) {
        PtClass clss = getxjClass(info.getFromClassId());// 升级后的班级
        Integer schoolYear = info.getSchoolYear();
        isCopyClassUser(null, clss.getFromClassId(), PtClassUser.TYPE_TEACHER,
                schoolYear + 1);
        PtOrg org = orgService.selectById(clss.getOrgId());
        // 根据学校和学段获取相应的科目集合
        List<Meta> subjectList = MetaUtils.getPhaseSubjectProvider()
                .listAllSubject(org.getId(), clss.getPhaseId(),
                        com.mainbo.utils.StringUtils.toIntegerArray(
                                org.getAreaIds().substring(1, org.getAreaIds().length() - 1),
                                ","));
        // 获取科目——教师map
        Map<Integer, Teacher> subjectteacherMap = ptClassUserService
                .getSubjectTeacherMap(clss.getId());
        m.addAttribute("subjectTeacherMap", subjectteacherMap);
        m.addAttribute("subjectTeacherList", getSubjectTeachers(subjectList, org.getId(), clss.getPhaseId()));
        m.addAttribute("ptClass", clss);
        fillNextClass(info.getFromClassId(), info.getClassIds(), m);
        m.addAttribute("classIds", info.getClassIds());
        m.addAttribute("schoolYear", info.getSchoolYear());
        return PREFIX + "classupdate/editClassTeacher.html";
    }

    private PtClass getxjClass(String fromClassId) {
        PtClass info = new PtClass();
        info.setFromClassId(fromClassId);
        return classMapper.selectOne(info);
    }

    private boolean isCopyClassUser(ClassUserMessage classUserVo,
                                    String oldClassId, Integer userType, Integer schoolYear) {
        PtClass xjClass = getxjClass(oldClassId);
        EntityWrapper<PtClassUser> model = new EntityWrapper<>();
        model.eq("class_id", xjClass.getId());
        model.eq("type", userType);
        if (classUserMapper.selectList(model).size() == 0) {
            if (PtClassUser.TYPE_STUDENT == userType
                    && classUserVo != null) {
                classUserVo.setOrgId(xjClass.getOrgId());
                classUserVo.setClassId(xjClass.getId());
                classUserVo.setType(PtClassUser.TYPE_STUDENT);
                classUserVo.setStartTime(new Date());
                List<PtClassUser> classUsers = this.ptClassUserService
                        .copyClassUsers(oldClassId, userType, schoolYear);
                classUserVo.setEndTime(new Date());
                classUserVo.setSchoolYear(schoolYear);
                classUserVo.setMessageType(com.mainbo.jms.MessageTypes.CLASS_STUDENT_INSERT.name());
                classUserVo.setClassUserList(classUsers);
            } else {
                this.ptClassUserService.copyClassUsers(oldClassId, userType, schoolYear);
            }
            return true;
        }
        return false;
    }


    /**
     * 升级：学生管理页
     *
     * @param info 班级
     * @param m    Model
     * @return String
     */
    @RequestMapping("/classupdate/editClassStudent")
    public String editClassStudent1(PtClass info, Model m) {
        PtClass clss = getxjClass(info.getFromClassId());// 升级后的班级
        Integer schoolYear = info.getSchoolYear();
        ClassUserMessage classUserVo = new ClassUserMessage();
        boolean isInsert = isCopyClassUser(classUserVo, clss.getFromClassId(),
                PtClassUser.TYPE_STUDENT, schoolYear + 1);
        if (isInsert) {
            jmsService.sendMessage(classUserVo);
        }
        EntityWrapper<PtClassUser> cu = new EntityWrapper<>();
        cu.eq("class_id", clss.getId());
        cu.eq("type", PtClassUser.TYPE_STUDENT);
        cu.eq("enable", 1);
        m.addAttribute("studentList", ptClassUserService.selectList(cu));
        m.addAttribute("ptClass", clss);
        m.addAttribute("schoolYear", schoolYear);
        m.addAttribute("classIds", info.getClassIds());
        fillNextClass(info.getFromClassId(), info.getClassIds(), m);
        return PREFIX + "classupdate/editClassStudent.html";
    }


    @RequestMapping("/classupdate/findStudentList/{classId}")
    @ResponseBody
    public Result findStudentList1(@PathVariable String classId) {
        Result result = new Result();
        EntityWrapper<PtClassUser> cu = new EntityWrapper<>();
        cu.eq("class_id", classId);
        cu.eq("type", PtClassUser.TYPE_STUDENT);
        cu.eq("enable", 1);
        List<PtClassUser> classUsers = ptClassUserService.selectList(cu);
        result.setCode(0);
        result.setData(classUsers);
        result.setCount(classUsers.size());
        return result;
    }

    /**
     * 学生添加页
     *
     * @param m
     * @return
     */
    @RequestMapping("/classupdate/addClassStudent")
    public String addClassStudent1(String classId, Student student, Model m) {
        List<Student> sList = studentService.findStudentsWithoutClass(student);
        m.addAttribute("item", student);
        m.addAttribute("classId", classId);
        m.addAttribute("studentList", sList);
        return PREFIX + "classupdate/classupdate_addStudent.html";
    }


    /**
     * @param info 班级
     * @param m    Model
     * @return String
     */
    @RequestMapping("/classupdate/toXjClassSuccess")
    public String toXjClassSuccess(PtClass info, Model m) {
        String orgId = "";
        Integer schoolYear = null;
        EntityWrapper<PtClass> oClasses = new EntityWrapper<>();
        EntityWrapper<PtClass> nClasses = new EntityWrapper<>();
        if (!StringUtils.isEmpty(info.getClassIds())) {
            List<String> updateClassIds = Arrays
                    .asList(info.getClassIds().split(","));
            nClasses.in("from_class_id", updateClassIds);
            oClasses.in("id", updateClassIds);
        }
        List<PtClass> newClasses = classMapper.selectList(nClasses);
        List<PtClass> oldClasses = classMapper.selectList(oClasses);
        for (PtClass classInfo : oldClasses) {
            if (StringUtils.isNotEmpty(classInfo.getClassroomId())) {
                PtSchoolClassroom classRoom = schoolClassroomMapper.selectById(classInfo.getClassroomId());
                if (classRoom != null) {
                    classRoom.setIsUsed(0);
                    schoolClassroomMapper.updateById(classRoom);
                }

                classInfo.setClassroomId("");
                classInfo.setClassroomName("");
                classMapper.updateById(classInfo);
            }
            orgId = classInfo.getOrgId();
            schoolYear = classInfo.getSchoolYear();
        }
        m.addAttribute("orgId", orgId);
        m.addAttribute("schoolYear", schoolYear);
        m.addAttribute("nClasses", newClasses);
        m.addAttribute("oClasses", oldClasses);
        this.ptClassService.changeClassStatus(info.getClassIds(),
                PtClass.update_success);
        // 升班成功，发送消息 {新班级信息，消息类型}
        List<ClassInfoMessage> udpates = new ArrayList<ClassInfoMessage>();
        for (PtClass n : newClasses) {
            ClassInfoMessage classVo = new ClassInfoMessage();
            BeanUtils.copyProperties(n, classVo);
            udpates.add(classVo);
        }
        ClassInfoMessage udpateVo = new ClassInfoMessage();
        udpateVo.setUpdates(udpates);
        udpateVo.setMessageType(MessageTypes.CLASS_UPDATE_XJ_CLASS.name());
        udpateVo.setSchoolYear(info.getSchoolYear() + 1);
        jmsService.sendMessage(udpateVo);
        return PREFIX + "classupdate/success.html";
    }

    /**
     * 选择毕业类型
     *
     * @param classId 班级
     * @param m       Model
     * @return String
     */
    @RequestMapping("/classupdate/toSelectGraduationStatus")
    public String toSelectGraduationStatus(String classId, Model m) {

        PtClass ptClass = classMapper.selectById(classId);
        ptClass.setGrade(MetaUtils.getMeta(ptClass.getGradeId()).getName());
        m.addAttribute("clzz", ptClass);
        return PREFIX + "classupdate/selectGraduationStatus.html";
    }

    @RequestMapping("/classupdate/toUpdateStu")
    public String toUpdateStu(PtClassUser um, PtClass classInfo,Integer graduateState,
                              Model model) {
        Integer gradeId = classInfo.getGradeId();
        EntityWrapper<PtClass> ci = new EntityWrapper<>();
        ci.eq("org_id", um.getOrgId());
        ci.eq("school_year", um.getSchoolYear());
        ci.eq("grade_id", gradeId);
        List<PtClass> classList = classMapper.selectList(ci);
        model.addAttribute("classList", classList);
        String classIds = "";
        String classId = um.getClassId();
        if (StringUtils.isEmpty(classId)) {
            for (PtClass temp : classList) {
                classIds += temp.getId() + ",";
            }
            classIds = classIds.substring(0, classIds.length() - 1);

        } else if (StringUtils.isNotEmpty(classId)) {
            classIds = classId;
        }
        Integer graduationStatus = classInfo.getGraduationStatus();
        model.addAttribute("model", um);
        model.addAttribute("clzz", classInfo);
        model.addAttribute("classIds", classIds);
        model.addAttribute("gradeId", gradeId);
        model.addAttribute("graduationStatus", graduationStatus);
        model.addAttribute("graduateState", graduateState);
        return PREFIX + "classupdate/studentList.html";


    }

    ;

    /**
     * 获取升级学生列表
     *
     * @param um        班级用户
     * @param classInfo 班级
     * @return String
     */
    @RequestMapping("/classupdate/findStudents")
    @ResponseBody
    public List<PtClassUser> findStudents(PtClassUser um, PtClass classInfo, String classIds) {

        List<PtClassUser> list = ptClassUserService
                .findClassStudentListByClassId(um, classInfo.getGraduationStatus(), classIds);
        for (PtClassUser classUser:list){
             classUser.setGrade(MetaUtils.getMeta(classInfo.getGradeId()).getName());
             classUser.setGraduationStatus(classInfo.getGraduationStatus());
        }
        return list;
    }
    /**
     * 改变用户毕业状态
     *
     * @param info
     *          班级
     * @param userIds
     *          用户id
     * @param m
     *          Model
     */
    @RequestMapping("/classupdate/chanageClassUserGraduationStatus")
    @ResponseBody
    public Result chanageClassUserGraduationStatus(PtClass info, String userIds) {
        Result result=new Result();
          result.setCode(Result.SUCCESS);
        try {
            if (!StringUtils.isEmpty(userIds)) {
                // 学生毕业消息
                ClassUserMessage um = new ClassUserMessage();
                um.setMessageType(MessageTypes.CLASS_STUDENT_GRADUATION.name());
                List<PtClassUser> clus = new ArrayList<>();
                List<String> ids = new ArrayList<String>();
                Set<String> classIds = new HashSet<String>();
                for (String id : userIds.split(",")) {
                    PtClassUser clu = ptClassUserService.selectById(id);
                    clus.add(clu);
                    ids.add(clu.getUserId());
                    classIds.add(clu.getClassId());
                }

                um.setClassUserList(clus);
                um.setGraduateState(info.getGraduationStatus());

                this.ptClassService.chanageStudentGraduationStatus(ids,
                        info.getGraduationStatus());
                if (PtClass.school_graduation.equals(info.getGraduationStatus())) {
                    accountService.changeAccountEnableStatus(ids, false, ClassInfoStatus
                            .getValueById(PtClass.school_graduation).getCname());
                }

                jmsService.sendMessage(um);

                List<String> changeClassIds = this.ptClassService
                        .changeClassinfoGraduation(classIds, info.getGraduationStatus());

                // 班级毕业消息
                if (changeClassIds.size() > 0) {
                    ClassInfoMessage infoMessage = new ClassInfoMessage();
                    infoMessage.setId(info.getClassIds());
                    infoMessage.setGraduateState(info.getGraduationStatus());
                    infoMessage.setMessageType(MessageTypes.CLASS_GRADUATION.name());
                    jmsService.sendMessage(infoMessage);
                }

            }
            result.setMsg("毕业成功");
        } catch (Exception e) {
            result.setCode(Result.FAIL);
            result.setMsg("操作失败");
            logger.error("班级毕业失败",e);
            e.printStackTrace();
        }
        return result;
    }
}
